package online.heycm.multipledb.config;

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * 用户模块数据源（默认）
 */
@Slf4j
@Configuration
@MapperScan(basePackages = {UserDataSourceConfig.MAPPER_PACKAGES}, sqlSessionFactoryRef = UserDataSourceConfig.SQL_SESSION_FACTORY)
public class UserDataSourceConfig {

    static final String MAPPER_PACKAGES = "online.heycm.multipledb.domain.user.mapper";
    static final String MAPPER_LOCATIONS = "classpath:/mapper/user/*.xml";
    static final String DATA_SOURCE = "userDataSource";
    static final String TRANSACTION_MANAGER = "userTransactionManager";
    static final String SQL_SESSION_FACTORY = "userSqlSessionFactory";

    @Autowired
    private HikariCPProperties hikariCPProperties;
    @Autowired
    private UserDBProperties dbProperties;

    @Bean(DATA_SOURCE)
    @Primary
    public DataSource dataSource() {
        log.info("init DataSource: [{}]...", DATA_SOURCE);
        HikariDataSource ds = new HikariDataSource();
        ds.setDriverClassName(dbProperties.getDriverClassName());
        ds.setJdbcUrl(dbProperties.getUrl());
        ds.setUsername(dbProperties.getUsername());
        ds.setPassword(dbProperties.getPassword());
        ds.setPoolName(dbProperties.getPoolName());
        ds.setMaximumPoolSize(hikariCPProperties.getMaximumPoolSize());
        ds.setMinimumIdle(hikariCPProperties.getMinimumIdle());
        ds.setConnectionTimeout(hikariCPProperties.getConnectionTimeout());
        ds.setIdleTimeout(hikariCPProperties.getIdleTimeout());
        ds.setAutoCommit(hikariCPProperties.getAutoCommit());
        log.info("init DataSource: [{}] success.", DATA_SOURCE);
        return ds;
    }

    @Bean(TRANSACTION_MANAGER)
    @Primary
    public DataSourceTransactionManager transactionManager(@Qualifier(DATA_SOURCE) DataSource ds) {
        log.info("init TransactionManager: [{}] success.", TRANSACTION_MANAGER);
        return new DataSourceTransactionManager(ds);
    }

    @Bean(SQL_SESSION_FACTORY)
    @Primary
    public SqlSessionFactory sqlSessionFactory(@Qualifier(DATA_SOURCE) DataSource ds) throws Exception {
        log.info("init SqlSessionFactory: [{}]...", SQL_SESSION_FACTORY);
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(ds);
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATIONS));
        // mybatis配置
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setLogImpl(StdOutImpl.class);
        factoryBean.setConfiguration(configuration);
        log.info("init SqlSessionFactory: [{}] success.", SQL_SESSION_FACTORY);
        return factoryBean.getObject();
    }

}
